<?php
/**
 * Library Of Shared Code (LOSC)
 *
 * LICENSE
 *
 * This source file is subject to the New BSD License that is bundled
 * with this package in the file LICENSE.txt.
 *
 * @category   LOSC Modules
 * @package    User
 * @subpackage Controllers
 * @copyright  Copyright (c) 2008 Robin Skoglund (http://robinsk.net/)
 * @license    http://creativecommons.org/licenses/BSD/  New BSD License
 */

/**
 * User_LoginController
 *
 * @category   LOSC Modules
 * @package    User
 * @subpackage Controllers
 * @copyright  Copyright (c) 2008 Robin Skoglund (http://robinsk.net/)
 * @license    http://creativecommons.org/licenses/BSD/  New BSD License
 */
class User_LoginController extends Zym_Controller_Action_Abstract
{
    /**
     * Session namespace
     *
     * @var Zend_Session_Namespace
     */
    protected $_session;
    
    /**
     * Flash redirector
     *
     * @var Zym_Controller_Action_Helper_FlashRedirector
     */
    protected $_flashRedirector;
    
    /**
     * Translator
     *
     * @var Zym_Controller_Action_Helper_Translator
     */
    protected $_translator;
    
    /**
     * Flash messenger
     *
     * @var Zend_Controller_Action_Helper_FlashMessenger
     */
    protected $_messenger;
    
    /**
     * Initializes controller
     *
     */
    public function init()
    {
        $this->getHelper('Layout')->setLayout('login');
        $this->_session    = new Zend_Session_Namespace(__CLASS__);
        $this->_appSession = $this->getHelper('AppSession')->getSession();
        $this->_translator = $this->getHelper('Translator');
        $this->_messenger  = $this->getHelper('FlashMessenger');
        $this->_flashRedirector = $this->getHelper('FlashRedirector');
    }
    
    /**
     * Returns login form
     *
     * @return User_Form_Login
     */
    public function getLoginForm()
    {
        return $this->getHelper('Form')->create('Login');
    }
    
    /**
     * Displays a login form
     * 
     */
    public function indexAction()
    {
        $auth = Zend_Auth::getInstance();
        
        // if already logged in, display another view script
        if ($auth->getIdentity()) {
            $this->render('loggedin');
            return;
        }
        
        // if redirected here from another place, add a message
        /*
        if ($this->_flashRedirector->hasRedirect()) {
            $msg = $this->_translator->_('Must be signed in to proceed');
            $this->_messenger->addMessage($msg);
        }
        //*/
        
        // get form, and validate if POST request
        $form = $this->getLoginForm();
        if ($this->getRequest()->isPost()) {
            $form->isValid($_POST);
        }
        
        // put login form in view
        $this->view->loginForm = $form->render();
    }
    
    /**
     * Processes a login request
     * 
     */
    public function processAction()
    {
        // redirect back to index if not POST
        if (!$this->getRequest()->isPost()) {
            $msg = $this->_translator->_('No data given');
            $this->_messenger->addMessage($msg);
            $this->_helper->redirector->gotoRouteAndExit(array(), 'login');
        }
        
        // get login form
        $form = $this->getLoginForm();
        
        // redirect back to index if form is invalid
        if (!$form->isValid($_POST)) {
            $msg = $this->_translator->_('Form contained invalid values');
            $this->_messenger->addMessage($msg);
            $this->view->loginForm = $form;
            $this->render('index');
            return;
        }
        
        // get values from form
        $username = $form->getValue('username');
        $password = $form->getValue('password');
        $remember = $form->getValue('remember') == '1';
        
        // set up auth adapter
        $authAdapter = new Losc_Security_Auth_Adapter_Doctrine();
        
        // use email column if username contains @
        if (strpos($username, '@') !== false) {
            $authAdapter->setUseEmail();
        }
        
        // set the given identity and credential
        $authAdapter->setIdentity($username)
                    ->setCredential($password);

        // get auth result
        $result = $authAdapter->authenticate();
        
        if (!$result->isValid()) {
            switch ($result->getCode()) {
                case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
                    $msg = 'Invalid user (%value%)';
                    $form->getElement('username')->addError($msg);
                    break;
                case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
                    $msg = 'The password is invalid';
                    $form->getElement('password')->addError($msg);
                    break;
                case Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS:
                    $msg = 'Unable to sign in, several users with the same id found';
                    $msg = $this->_translator->_($msg);
                    $this->_messenger->addMessage($msg);
                    break;
                default:
                    $msg = 'Unable to sign in. An unknown error occured when authenticating';
                    $msg = $this->_translator->_($msg);
                    $this->_messenger->addMessage($msg);
                    break;
            }
            
            // result is invalid, show form again
            $this->view->loginForm = $form;
            $this->render('index');
            return;
        }

        // login successful, store uid
        Zend_Auth::getInstance()->getStorage()->write($authAdapter->getUsername());
        
        // remember login?
        if ($remember) {
            Zend_Session::rememberMe();
            $_SESSION['remember'] = true;
        }
        
        // redirected to login page from another page?
        if ($this->_flashRedirector->hasRedirect()) {
            // yes, redirect back
            $this->_flashRedirector->redirect();
        } else {
            // no, redirect to home page
            $this->_helper->redirector->gotoRouteAndExit(array(), 'home', true);
        }
    }
    
    /**
     * Logs out user if logged in
     *
     */
    public function logoutAction()
    {
        Zend_Session::forgetMe();
        Zend_Session::expireSessionCookie();
        $this->_helper->_redirector->gotoRouteAndExit(array(), 'home');
    }
    
    /**
     * Shows help on signing in
     *
     */
    public function helpAction()
    {
        
    }
    
    /**
     * Displays information on how to reset password
     *
     */
    public function forgotAction()
    {
        $form = $this->getHelper('Form')->create('Forgot');
        
        $this->view->forgotForm = $form->render();
    }
    
    /**
     * Process a "I have forgot my password" form
     * 
     */
    public function forgotProcessAction()
    {
        // redirect back to index if not POST
        if (!$this->getRequest()->isPost()) {
            $msg = $this->_translator->_('No data given');
            $this->_messenger->addMessage($msg);
            $this->_goto('forgot', 'login', 'user');
        }
        
        // get form
        $form = $this->getHelper('Form')->create('Forgot');
        
        // redirect back to index if form is invalid
        if (!$form->isValid($_POST)) {
            $msg = $this->_translator->_('Form contained invalid values');
            $this->_messenger->addMessage($msg);
            $this->view->forgotForm = $form;
            $this->render('forgot');
            return;
        }
        
        // TODO: implement
        exit('// TODO: implement');
    }
}
